package com.literaryfamily.literaryfamily.service.payment.impl;

import com.alipay.api.AlipayClient;
import com.literaryfamily.literaryfamily.dao.BookTradeStatesMapper;
import com.literaryfamily.literaryfamily.dao.PaymentsMapper;
import com.literaryfamily.literaryfamily.entity.DiscountPrice;
import com.literaryfamily.literaryfamily.entity.Payments;
import com.literaryfamily.literaryfamily.entity.PaymentsExample;
import com.literaryfamily.literaryfamily.enumPackage.OperatorStatic;
import com.literaryfamily.literaryfamily.enumPackage.OperatorType;
import com.literaryfamily.literaryfamily.enumPackage.PaymentMethod;
import com.literaryfamily.literaryfamily.exceptions.OperationException;
import com.literaryfamily.literaryfamily.model.ReturnResult;
import com.literaryfamily.literaryfamily.myUtil.PageUtil;
import com.literaryfamily.literaryfamily.myUtil.StringUtil;
import com.literaryfamily.literaryfamily.service.payment.PaymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
@Transactional(noRollbackFor = OperationException.class)
public class PaymentServiceImpl implements PaymentService {
	@Autowired
	BookTradeStatesMapper bookTradeStatesMapper;
	@Autowired
	PaymentsMapper paymentsMapper;
	@Autowired
	AlipayClient alipayClient;

	@Override
	public ReturnResult<String> placeAnOrder(Payments payments, List<DiscountPrice> discountPrice, int type) {
		BigDecimal paymentAmount = payments.getPaymentAmount();
		if (paymentAmount.compareTo(BigDecimal.ZERO) < 0) {
			return ReturnResult.isFalse("错误!支付金额不可为负数");
		}
		//设置状态为待支付
		payments.setPaymentStatus(OperatorStatic.UNPAID.getStaticNum());
		//获取事件单据号
		String transactionId = payments.getTransactionId();
		//根据单号获取类型
		OperatorType staticByPrefix = OperatorType.getStaticByPrefix(StringUtil.extractPrefix(transactionId, 2));
		//检查类型是否合法
		switch (staticByPrefix) {
			case SALE:
			case BORROW:
				return placeOrder(payments, discountPrice, type);
			case RETURN:
				break;
			default:
				throw new OperationException("错误的单据类型!");
		}
		//向外支付,之后再说
		return null;
	}

	/**
	 * 处理买卖/借阅单
	 */
	private ReturnResult<String> placeOrder(Payments p, @Nullable List<DiscountPrice> discountPrice, int type) {
		//处理订单
		p = StringUtil.setNull(p);
		if (p == null || p.getId() == null || p.getTransactionId() == null)
			throw new OperationException("错误!订单为空");
		BigDecimal paymentAmount = new BigDecimal(0);
		//支付金额和交易信息
		paymentAmount = paymentAmount.add(p.getPaymentAmount());
		p.setPaymentStatus(OperatorStatic.UNPAID.getStaticNum());
		PaymentMethod paymentMethod = PaymentMethod.getPaymentMethod(p.getPaymentMethod());
		//折扣
		BigDecimal discountAmount = BigDecimal.ZERO;
		if (discountPrice != null && !discountPrice.isEmpty()) {
			for (DiscountPrice dp : discountPrice) {
				// 过滤掉无效券
				if (dp.getIsUse() || (dp.getExpirationTime() != null && dp.getExpirationTime().before(new Date()))) {
					continue;
				}

				// 折扣券基础信息
				BigDecimal discount = BigDecimal.valueOf(dp.getDiscount()); // 例如 0.8 表示 8 折
				BigDecimal maxAmount = dp.getMaxAmount() != null ? dp.getMaxAmount() : BigDecimal.ZERO;

				// 计算当前优惠金额 = 总价 * (1 - 折扣)，并与最大金额比较
				BigDecimal currentDiscount = paymentAmount.multiply(BigDecimal.ONE.subtract(discount));
				currentDiscount = currentDiscount.min(maxAmount);

				// 如果当前折扣券不允许与其他券叠加，则只使用这一张
				if (dp.getIsOnly()) {
					discountAmount = currentDiscount;
					break;
				}
				// 否则累加到总折扣金额中
				discountAmount = discountAmount.add(currentDiscount);
			}
			//最大为原来的90%
			BigDecimal min;
			min = paymentAmount.subtract(discountAmount);
			paymentAmount = min.max(paymentAmount.multiply(BigDecimal.valueOf(0.3)));
		}
		Payment payment = Payment.getPayment(paymentMethod);
		if (payment == null) return ReturnResult.isFalse("错误!不支持的支付方式");
		try {
			return
					payment.placeAnOrder(
							paymentAmount.toString(),
							p.getPaymentAccount(),
							p.getTransactionDescription(),
							p.getTransactionId(),
							type);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public ReturnResult<Payments> updateOrder(Payments p) throws Exception {
		Payment payment = Payment.getPayment(PaymentMethod.getPaymentMethod(p.getPaymentMethod()));
		if (payment == null) throw new OperationException("错误!不支持的支付方式");
		try {
			return payment.selectOrderByTransactionId(p.getTransactionId());
		} catch (Exception e) {
			if (e instanceof OperationException) {
				throw e;
			}
			throw new RuntimeException(e);
		}
	}

	@Override
	public ReturnResult<Payments> closeOrder(Payments p, String msg) {
		Payment payment = Payment.getPayment(PaymentMethod.getPaymentMethod(p.getPaymentMethod()));
		if (payment == null) throw new OperationException("错误!不支持的支付方式");
		try {
			ReturnResult<Boolean> booleanReturnResult = payment.closeOrderByTransactionId(p.getTransactionId(), msg);
			return ReturnResult.isTrue(booleanReturnResult);
		} catch (Exception e) {
			if (e instanceof OperationException) {
				throw ((OperationException) e);
			}
			throw new RuntimeException(e);
		}
	}

	@Override
	public List<Payments> selectOrderByTransactionId(List<String> p) {
		PaymentsExample paymentsExample = new PaymentsExample();
		paymentsExample.createCriteria().andTransactionIdIn(p);
		paymentsExample.or().andExternalOrdersIn(p);
		paymentsExample.or().andPaymentsIdIn(p);
		return paymentsMapper.selectByExample(paymentsExample);
	}

	@Override
	public ReturnResult<Payments> listUserOrders(Long userId, int page, int size) {
		return ReturnResult.isTrue("查询成功", paymentsMapper.selectUserPaymentHistory(userId, new PageUtil(page, size)), null);
	}
}